fix(plugin-access-manager): set Casdoor initDataNewOnly=true to preserve API state#1418
fix(plugin-access-manager): set Casdoor initDataNewOnly=true to preserve API state#1418jeffersonrodrigues92 wants to merge 1 commit into
Conversation
WalkthroughThe PR adds a new ChangesAuth Backend Configuration
Comment |
…rve API state Casdoor v2.206.0 defaults to initDataNewOnly=false, which causes the backend to DELETE+INSERT every entity present in init_data.json on every restart (applications, roles, groups, permissions, etc.). Any runtime modification performed via the Casdoor UI/API on a JSON-listed entity — including application↔permission associations, role/user bindings, and resource lists — is silently reset to the JSON state at that point. This was confirmed in production after a recent plugin-auth deploy: applications kept their identity but lost the permission associations that had been wired up via the Casdoor API. Source reference: casdoor/casdoor@v2.206.0 object/init_data.go:initDefinedApplication (and initDefinedPermission). With initDataNewOnly=true, existing entries are skipped — only new entries (entities in JSON but not in DB) are inserted, preserving everything an operator has touched via API/UI. Trade-offs: - ✅ API/UI-managed associations survive restarts - ✅ First-time installs (empty DB) still bootstrap from JSON correctly - ✅ Adding new entries to init_data.json still works on next restart -⚠️ Updating an EXISTING entry's actions/resources via init_data.json becomes a no-op on environments that already have it. Updates must go through casdoor-migrations SQL scripts (the canonical path that init/casdoor-migrations/migrations/ already uses). Plan-to-rollout: - Merge to main → propagates via helmfile to dev/sandbox/stg/prd - Develop deploys to Firmino — QA validates that: 1. App↔permission associations persist after a Casdoor pod restart 2. New seed entries added via init_data.json still get created on fresh installs 3. No regression in user→role→group→app flow X-Lerian-Ref: 0x1
6cf68ce to
8c5342c
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@charts/plugin-access-manager/templates/auth-backend/configmap.yaml`:
- Line 22: The change mixes adding the quote function to the template with the
unrelated initDataNewOnly change; revert the quote addition on the initDataFile
template line (the expression using initDataFile) in this PR so only
initDataNewOnly is included, then create a follow-up commit that solely updates
initDataFile to use {{ .Values.auth.backend.initDataFile | default
"./init_data.json" | quote }} to ensure YAML escaping; reference the template
key initDataFile when making these commits to keep the changes isolated and
clear.
- Line 23: Add a documented default for the missing values key by editing the
chart values file to include auth.backend.initDataNewOnly with a clear
description and a default value (true), explaining it controls whether
API/UI-managed state is preserved across restarts; place it under the existing
auth.backend block near related backend settings so templating
(.Values.auth.backend.initDataNewOnly) finds the documented default and users
understand the purpose (preserve API/UI-managed state on restart).
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 51fddc6f-ce85-4986-bda8-60f847db9a01
📒 Files selected for processing (1)
charts/plugin-access-manager/templates/auth-backend/configmap.yaml
| quota: '{"organization": -1, "user": -1, "application": -1, "provider": -1}' | ||
| logConfig: '{"filename": "logs/casdoor.log", "maxdays": 99999, "perm": "0770"}' | ||
| initDataFile: {{ .Values.auth.backend.initDataFile | default "./init_data.json" | quote }} No newline at end of file | ||
| initDataFile: {{ .Values.auth.backend.initDataFile | default "./init_data.json" | quote }} |
There was a problem hiding this comment.
🧹 Nitpick | 🔵 Trivial | 💤 Low value
Consider splitting the quote addition into a separate commit.
While adding quote to initDataFile is a good practice, it's technically a separate change from the initDataNewOnly addition. The quote function ensures proper YAML escaping, but this modification could have been isolated for clarity.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@charts/plugin-access-manager/templates/auth-backend/configmap.yaml` at line
22, The change mixes adding the quote function to the template with the
unrelated initDataNewOnly change; revert the quote addition on the initDataFile
template line (the expression using initDataFile) in this PR so only
initDataNewOnly is included, then create a follow-up commit that solely updates
initDataFile to use {{ .Values.auth.backend.initDataFile | default
"./init_data.json" | quote }} to ensure YAML escaping; reference the template
key initDataFile when making these commits to keep the changes isolated and
clear.
| logConfig: '{"filename": "logs/casdoor.log", "maxdays": 99999, "perm": "0770"}' | ||
| initDataFile: {{ .Values.auth.backend.initDataFile | default "./init_data.json" | quote }} No newline at end of file | ||
| initDataFile: {{ .Values.auth.backend.initDataFile | default "./init_data.json" | quote }} | ||
| initDataNewOnly: {{ .Values.auth.backend.initDataNewOnly | default "true" | quote }} |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Description: Check if initDataNewOnly is documented in values.yaml
# Search for initDataNewOnly in values.yaml files
fd -t f 'values.yaml' charts/plugin-access-manager/ --exec rg -n 'initDataNewOnly' {} \;
# Also check for the auth.backend.initDataNewOnly path
fd -t f 'values.yaml' charts/plugin-access-manager/ --exec cat {} \; | grep -A5 -B5 'backend:' | grep -i 'initData'Repository: LerianStudio/helm
Length of output: 43
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# 1) Find all usages of initDataNewOnly anywhere in the repo
echo "== RG initDataNewOnly =="
rg -n --hidden --no-ignore initDataNewOnly . || true
# 2) Locate values.yaml files for this chart (and nearby charts)
echo
echo "== values.yaml files under charts/plugin-access-manager =="
fd -t f 'values.yaml' charts/plugin-access-manager --full-path
# 3) For each discovered values.yaml under that chart, show whether auth.backend exists
echo
echo "== auth.backend section context in chart values.yaml files =="
while IFS= read -r f; do
echo "--- $f ---"
# Show lines around "auth:" and "backend:" and "initData"
rg -n '(^|[[:space:]])auth:|(^|[[:space:]])backend:' "$f" || true
rg -n 'initData' "$f" || true
done < <(fd -t f 'values.yaml' charts/plugin-access-manager --full-path)
# 4) Also check chart-level defaults if they exist elsewhere (e.g., values/*.yaml)
echo
echo "== Any files under plugin-access-manager named values*.yaml =="
fd -t f 'values*.ya?ml' charts/plugin-access-manager --full-pathRepository: LerianStudio/helm
Length of output: 485
🏁 Script executed:
#!/bin/bash
set -euo pipefail
VALUES_FILE="charts/plugin-access-manager/values.yaml"
echo "== initDataNewOnly in values.yaml =="
rg -n 'initDataNewOnly' "$VALUES_FILE" || true
echo
echo "== auth.backend block vicinity in values.yaml =="
# Print a small window around any auth/backend occurrence
rg -n '(^|[[:space:]])auth:|(^|[[:space:]])backend:' "$VALUES_FILE" || true
echo
echo "== Attempt to show lines around auth/backend keys (if present) =="
# If file is small enough, show a larger slice for manual reading
python3 - <<'PY'
import itertools
path="charts/plugin-access-manager/values.yaml"
with open(path,'r',encoding='utf-8') as f:
lines=f.readlines()
# Print up to first 200 lines (usually enough for auth config in values.yaml)
for i,line in enumerate(lines[:200], start=1):
if any(k in line for k in ["auth:", "backend:", "initData"]):
print(f"{i:4d}:{line.rstrip()}")
PYRepository: LerianStudio/helm
Length of output: 339
🏁 Script executed:
#!/bin/bash
set -euo pipefail
VALUES_FILE="charts/plugin-access-manager/values.yaml"
echo "== initData occurrences in values.yaml =="
rg -n 'initData' "$VALUES_FILE" || true
echo
echo "== Show auth/backend sections around the reported lines =="
# Dump ~60 lines around each occurrence of "backend:" and each "auth:" occurrence after/before
python3 - <<'PY'
path="charts/plugin-access-manager/values.yaml"
with open(path,'r',encoding='utf-8') as f:
lines=f.readlines()
def dump_around(center, half=35):
start=max(center-half,1)
end=min(center+half,len(lines))
for i in range(start,end+1):
print(f"{i:4d}:{lines[i-1].rstrip()}")
for c in [144, 289, 383, 424]:
print("\n--- context around", c, "---")
dump_around(c, half=35)
PYRepository: LerianStudio/helm
Length of output: 9705
Document .Values.auth.backend.initDataNewOnly in charts/plugin-access-manager/values.yaml
The template sets:
initDataNewOnly: {{ .Values.auth.backend.initDataNewOnly | default "true" | quote }}…but charts/plugin-access-manager/values.yaml does not define auth.backend.initDataNewOnly under the existing auth.backend: block (so the option is undocumented). Add the key with a description of what it controls (preserving API/UI-managed state on restart).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@charts/plugin-access-manager/templates/auth-backend/configmap.yaml` at line
23, Add a documented default for the missing values key by editing the chart
values file to include auth.backend.initDataNewOnly with a clear description and
a default value (true), explaining it controls whether API/UI-managed state is
preserved across restarts; place it under the existing auth.backend block near
related backend settings so templating (.Values.auth.backend.initDataNewOnly)
finds the documented default and users understand the purpose (preserve
API/UI-managed state on restart).
Problem
After a recent
plugin-authdeploy that touchedinit_data.json(PR LerianStudio/plugin-auth#557), production applications kept their identity but lost the application↔permission associations that had been wired up via the Casdoor UI/API. The applications themselves were not deleted — only the manually-configured links to permissions disappeared.Root cause
The plugin-access-manager Helm chart relies on Casdoor v2.206.0's default
initDataNewOnly = false. With that default, every Casdoor restart re-processes the entireinit_data.jsonand performs a DELETE + INSERT cycle on every entity that already exists in the database:The same logic is mirrored in
initDefinedPermission,initDefinedRole,initDefinedGroup, etc. Any field on those entities that was customized at runtime (users list, roles list, resources, permission references on an application) is silently reset to whatever is ininit_data.jsonon every Casdoor pod restart.This was masked in steady state because Casdoor pods were long-lived. The recent deploy forced a restart, which exposed the wipe.
Fix
Add
initDataNewOnlyto the auth-backend ConfigMap, parameterized via Values (default"true") to match the existing pattern oninitDataFile:With
initDataNewOnly: "true"Casdoor's behavior changes to:owner+name) is already in the DB → SKIP (no delete, no insert, no update).Operators that ever need the legacy reset-on-restart behavior can opt out per-environment by setting
auth.backend.initDataNewOnly: "false"in values.Behavior matrix
=false)=truedefault)Trade-off and ops impact
init_data.json.init_data.jsonstill works on next restart (they get INSERTed).actions/resources/etc. viainit_data.jsonbecomes a no-op on environments that already have it. Future updates must use the SQL migration path already in place atinit/casdoor-migrations/migrations/(which is the canonical channel — see migrations 16, 28, 29 for bank-transfer/pix-btg precedent).Rollout plan
This PR targets
developso that the chart is released as a*-beta.Nversion first and validated in Firmino before promotion tomain(final release).develop→ semantic-release publishes avX.Y.Z-beta.Nchart versioninit_data.jsonon a separate test still results in INSERT on the next pod cycle (proves seed expansion still works)develop→main(standard back-merge) to publish the release versionOperator communication
After release, any future RBAC update on an existing entity must go via SQL migration in
LerianStudio/plugin-auth/init/casdoor-migrations/migrations/, not by editinginit_data.json. This matches whatmigrations/16_add_bank_transfer_permissions.up.sql,28_add_bank_transfer_system_config_permissions.up.sql, and29_add_pix_indirect_btg_webhooks_operator_permissions.up.sqlalready model. For brand-new entities (resources/permissions/roles/groups that don't exist anywhere yet),init_data.jsoncontinues to be the right channel.Plugin-auth side
No changes required in
LerianStudio/plugin-auth:init/casdoor/app.conf/in that repo is an empty directory — the Dockerfile does not copy any customapp.confinto the imageenvFrom: configMapRef)initDataNewOnlyConfigMap key propagates directly to Casdoor as the env overrideReferences